package com.asd.netty.netty.server;

import com.alibaba.fastjson.JSON;
import com.asd.netty.netty.common.InformationRepository;
import com.asd.netty.entity.Information;
import com.asd.netty.netty.common.*;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleStateEvent;
import io.netty.util.ReferenceCountUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import static com.asd.netty.netty.common.PacketProto.Packet;
/**
 * @author LRL
 */
@Slf4j
@Component
public class ServerHeartbeatHandler extends ChannelInboundHandlerAdapter {

    /**心跳丢失计数器**/
    private int counter;

//    @Autowired
//    private InformationRepository repository;

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info(ctx.channel().remoteAddress().toString() + ": 服务器成功连接到客户端！");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.error(ctx.channel().remoteAddress().toString() + ": 服务器与客户端断开连接！");
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        /**判断接收到的包类型**/
        log.info("msg="+msg.toString());
        if (msg instanceof Packet) {
            Packet packet = (Packet) msg;
            //获取命令执行器
            switch (packet.getPacketType()) {
                case HEARTBEAT:
                    handleHeartbreat(ctx, packet);
                    break;
                case DATA:
                    handleData(ctx, packet);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        if (evt instanceof IdleStateEvent) {
            /**空闲6s之后触发 (心跳包丢失)**/
            if (counter >= 3) {
                /**连续丢失3个心跳包 (断开连接)**/
                ctx.channel().close().sync();
                log.info("与客户端断开连接!");
            } else {
                counter++;
                log.info("丢失了第" + counter + " 个心跳包！");
            }
        }
    }

    /**
     * 异常处理
     * @param ctx
     * @param cause
     * @throws Exception
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause){
        log.info("连接出现异常");
        cause.printStackTrace();
    }

    /**
     * 处理心跳包
     *
     * @param ctx
     * @param packet
     */
    private void handleHeartbreat(ChannelHandlerContext ctx, Packet packet) {
        // 将心跳丢失计数器置为0
        counter = 0;
        log.info("收到心跳!");
        ReferenceCountUtil.release(packet);
    }

    /**
     * 处理数据包
     *
     * @param ctx
     * @param packet
     */
    private void handleData(ChannelHandlerContext ctx, Packet packet) {

        /**将心跳丢失计数器置为0**/
        ByteBuf readBuffer;
        counter = 0;
        String data = packet.getData();
        byte[] bytes = data.getBytes();
        Information information = new Information();
        readBuffer = BufferFactory.getBuffer(bytes);
        Charset CHARSET = Charset.forName("UTF-8");
        byte[] byteszizhi = new byte[5];
        readBuffer.readBytes(byteszizhi);
        String theme =  new String(byteszizhi, CHARSET);
        System.out.println("地址: "+ theme);
        readBuffer.readByte();
        int length = readBuffer.readShort();
        System.out.println("长度： "+length);
        List<Object> array=new ArrayList();
        for (int i = 0; i <length; i++) {
            if (bytes !=null){
                int value= readBuffer.readShort();
                readBuffer.readByte();
                System.out.println("数据段： "+ value);
                String str = String.valueOf(value);
                array.add(str);
            }
            break;
        }
        System.out.println("数组："+array);
        information.setTheme(theme);
        information.setLength(length);
        information.setData(array.toString());
//        this.repository.save(information);
        JSON.toJSONString(information);
        log.info("接收到的数据 ："+data);
        ReferenceCountUtil.release(packet);
    }

}
